const view_root = {
  template: `
<div style="width: 100%; height: 100%;" class="ma-2">
    <el-row>
        <el-button-group>
            <el-button icon="el-icon-download" type="success" @click="btnFormat">格式化</el-button>
            <el-button icon="el-icon-upload2" type="primary" @click="btnFormatSlim">压缩</el-button>
        </el-button-group>

        <el-button-group>
            <el-button icon="el-icon-s-fold" type="info" @click="btnEscapeJson">转义</el-button>
            <el-button icon="el-icon-s-unfold" type="info" @click="btnUnescapeJson">去除转义</el-button>
        </el-button-group>

        <el-button-group>
            <el-button icon="el-icon-s-fold" type="info" @click="btnToA">Unicode转中文</el-button>
            <el-button icon="el-icon-s-unfold" type="info" @click="btnToUnicode">中文转Unicode</el-button>
        </el-button-group>

        <el-button icon="el-icon-delete" type="danger" @click="btnCleanAll">清空</el-button>
    </el-row>

    <pre id="editor" style="height: calc(100% - 140px);">{"status":200,"text":"","error":null,"data":[{"news_id":51184,"title":"发布最新 iPhone X Review: Innovative future with real black technology","source":"Netease phone"},{"news_id":51183,"title":"Traffic paradise: How to design streets for people and unmanned vehicles in the future?","source":"Netease smart","link":"http://netease.smart/traffic-paradise/1235"},{"news_id":51182,"title":"Teslamask's American Business Relations: The government does not pay billions to build factories","source":"AI Finance","members":["Daniel","Mike","John"]}]}</pre>
  
    <div class="my-2">
      <el-breadcrumb separator=",">
        <el-breadcrumb-item>行{{mRowNumber}}</el-breadcrumb-item>
        <el-breadcrumb-item>列{{mColumnNumber}}</el-breadcrumb-item>
      </el-breadcrumb>
    </div>

    <el-alert
      v-if="mException"
      :title="mException.toString()"
      type="error"
      show-icon>
    </el-alert>    
</div>`,
  data: function () {
    return {
      mEditor: null,
      mException: null,

      // editor
      mRowIndex: 0,
      mColumnIndex: 0,
    };
  },

  computed: {
    mRowNumber: function () {
      return this.mRowIndex + 1;
    },
    mColumnNumber: function () {
      return this.mColumnIndex + 1;
    },
  },
  mounted: function () {
    //#region ace.js 基础用法

    const editor = ace.edit("editor");

    // 你可以通过setTheme来设置主题，需要注意的是主题文件要存在，并且需要与ace.js同级，命名规则为theme-主题名.js
    // editor.setTheme("ace/theme/terminal");
    // editor.setTheme("ace/theme/sqlserver");
    editor.setTheme("ace/theme/github");

    // 默认情况下编辑器为纯文本模式，你可以通过setMode来设置编辑器对应的语言模式，例如你想让其匹配 json，
    // 就可以像下边这样配置，同样需要语言模式的文件存在，文件与ace.js同级，命名规则为mode-语言模式.js
    editor.session.setMode("ace/mode/json");

    // editor.setFontSize(22); // 通过setFontSize可以设置编辑器内文本字体的大小
    editor.getSession().setTabSize(4); // 通过setTabSize可以设置制表符的长度
    editor.session.setUseSoftTabs(true); // 同时可以通过setUseSoftTabs将制表符变成对应长度的空格
    editor.setReadOnly(false); // 如果你不想编辑，可以通过setReadOnly可以将编辑器设置为只读模式
    editor.setShowPrintMargin(false); // 默认情况下ace编辑器中会有一道竖线标识打印的边距，可以通过setShowPrintMargin来控制其是否显示

    this.mEditor = editor;

    // 注册事件 - 监控光标位置
    editor.on("changeSelection", () => {
      const p = editor.getCursorPosition();
      this.mRowIndex = p.row;
      this.mColumnIndex = p.column;
    });

    //#endregion
  },
  methods: {
    btnFormat: function () {
      try {
        const jsonStr = this.mEditor.getSession().getValue();

        const jsonObj = JSON.parse(jsonStr);
        const formatted = JSON.stringify(jsonObj, null, 2);

        this.mEditor.getSession().setValue(formatted);

        this.mException = undefined;
      } catch (e) {
        this.mException = e;
      }
    },

    btnFormatSlim: function () {
      try {
        const jsonStr = this.mEditor.getSession().getValue();

        const jsonObj = JSON.parse(jsonStr);
        const formatted = JSON.stringify(jsonObj);

        this.mEditor.getSession().setValue(formatted);
      }
      catch (e) {
        this.mException = e;
      }
    },

    btnEscapeJson: function () {
      const content = this.mEditor.getSession().getValue();

      let r = content.replace(/(["\\\/\b\f\n\r\t])/g, function (match) {
        switch (match) {
          case '"':
            return '\\"'; // 双引号
          case "\\":
            return "\\\\"; // 反斜杠
          case "/":
            return "/"; // 斜线
          case "\b":
            return "\\b"; // 退格符
          case "\f":
            return "\\f"; // 换页符
          case "\n":
            return "\n"; // 换行符
          case "\r":
            return "\r"; // 回车符
          case "\t":
            return "\\t"; // 制表符
          default:
            return match; // 其他字符原样输出
        }
      });

      this.mEditor.getSession().setValue(r);
    },

    btnUnescapeJson: function () {
      const str = this.mEditor.getSession().getValue();

      let r = str
        .replace(/\\n/g, "\n")
        .replace(/\\t/g, "\t")
        .replace(/\\r/g, "\r")
        .replace(/\\b/g, "\b")
        .replace(/\\f/g, "\f")
        .replace(/\\"/g, '"')
        .replace(/\\\\/g, "\\")
        .replace(/\\u([\dA-Fa-f]{4})/g, function (match, p1) {
          return String.fromCharCode(parseInt(p1, 16));
        })
        .replace(/%u([\dA-Fa-f]{4})/g, function (match, p1) {
          return decodeURIComponent(match);
        });

      this.mEditor.getSession().setValue(r);
    },

    btnToA: function () {
      const str = this.mEditor.getSession().getValue();

      let r = str
        .replace(/\\u([\dA-Fa-f]{4})/g, function (match, p1) {
          return String.fromCharCode(parseInt(p1, 16));
        })
        .replace(/%u([\dA-Fa-f]{4})/g, function (match, p1) {
          return decodeURIComponent(match);
        });

      this.mEditor.getSession().setValue(r);
    },

    btnToUnicode: function () {
      const str = this.mEditor.getSession().getValue();

      // [\u4E00-\u9FA5] 中文
      let r = str.replace(/[\u4E00-\u9FA5]/g, function (match) {
        return "\\u" + ("0000" + match.charCodeAt(0).toString(16)).slice(-4);
      });

      this.mEditor.getSession().setValue(r);
    },

    btnCleanAll: function () {
        this.mEditor.getSession().setValue("");
    },

    //#region json 解析结构

    //   function escapeJsonManual(obj) {
    //     if (typeof obj !== 'object') {
    //       throw new Error('Input must be an object.');
    //     }

    //     function escapeString(str) {
    //       return str.replace(/[\u0000-\u001f\"\\]/g, function(match) {
    //         if (match === '"') {
    //           return '\\"';
    //         } else if (match === '\\') {
    //           return '\\\\';
    //         } else if (match === '\b') {
    //           return '\\b';
    //         } else if (match === '\f') {
    //           return '\\f';
    //         } else if (match === '\n') {
    //           return '\\n';
    //         } else if (match === '\r') {
    //           return '\\r';
    //         } else if (match === '\t') {
    //           return '\\t';
    //         } else {
    //           // 对于其他不可打印字符，使用 Unicode 转义
    //           return '\\u00' + ('00' + match.charCodeAt(0).toString(16)).slice(-4);
    //         }
    //       });
    //     }

    //     function stringify(value, indent, gap, level) {
    //       if (typeof value === 'string') {
    //         return '\\"' + escapeString(value) + '\\"';
    //       } else if (value === null) {
    //         return 'null';
    //       } else if (Array.isArray(value)) {
    //         if (value.length === 0) {
    //           return '[]';
    //         }
    //         let result = '[';
    //         for (let i = 0; i < value.length; i++) {
    //           if (i > 0) {
    //             result += ',';
    //           }
    //           result += stringify(value[i], indent, gap, level + 1);
    //         }
    //         result += ']';
    //         return result;
    //       } else if (typeof value === 'object') {
    //         if (Object.keys(value).length === 0) {
    //           return '{}';
    //         }
    //         let result = '{';
    //         let keys = Object.keys(value);
    //         for (let i = 0; i < keys.length; i++) {
    //           if (i > 0) {
    //             result += ',';
    //           }
    //           let key = keys[i];
    //           // result += '"' + escapeString(key) + '": ' + stringify(value[key], indent, gap, level + 1); // Edit By Howe
    //           result += '\\"' + escapeString(key) + '\\":' + stringify(value[key], indent, gap, level + 1); // Edit By Howe
    //         }
    //         result += '}';
    //         return result;
    //       } else if (typeof value === 'number' || typeof value === 'boolean') {
    //         return String(value);
    //       } else {
    //         throw new Error('Unsupported value type.');
    //       }
    //     }

    //     return stringify(obj, '', '', 0);
    // }

    //#endregion
  },
};
